<template>
  <div class="home">
    <div class="header">
      <div class="title">历史学习助手</div>
      <!-- <div class="menu">
        <div
          class="item"
          v-for="(item, index) in menuList"
          :key="index"
          :class="[activeMenu == item.title ? 'active' : '']"
          @click="selectMenu(item)"
        >
          {{ item.title }}
        </div>
      </div> -->
    </div>
    <div class="container">
      <div class="example">
        <div class="title">示例</div>
        <div
          class="item"
          @click="setInputValue(item.tip)"
          v-for="(item, index) in activeExample"
          :key="index"
        >
          {{ item.tip }}
        </div>
      </div>
      <div class="content">
        <div class="inputWrap">
          <div class="title">输入</div>
          <el-input
            v-model="inputText"
            :rows="20"
            type="textarea"
            placeholder="请输入"
          />
        </div>
        <div class="outputWrap">
          <div class="title">输出</div>
          <el-input
            v-model="outputText"
            :rows="20"
            type="textarea"
            placeholder="智能生成结果展示"
          />
        </div>
      </div>
      <div class="footBtn">
        <el-button @click="clearAll">清空</el-button>
        <el-button type="primary" @click="chatPost">生成</el-button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, reactive, toRefs } from "vue";
import axios from "axios";
let menuList = ref([
  { id: 1, title: "历史学习助手", key: "sql" },
  // {
  //   id: 2,
  //   title: "智能生成Excel公式",
  //   key: "excel",
  // },
  // {
  //   id: 3,
  //   title: "英文助手",
  //   key: "English",
  // },
]);
let exampleList = ref({
  sql: [
    {
      tip: "帮我生成初中历史的常见知识点",
    },
  ],

});
let inputText = ref("");
let outputText = ref("");
let activeMenu = ref("历史学习助手");
let activeExample = ref(null);
onMounted(() => {
  activeExample.value = exampleList.value["sql"];
  console.log(activeExample.value);
});
//选择导航
const selectMenu = (item) => {
  activeMenu.value = item.title;
  activeExample.value = exampleList.value[item.key];
};
//设置输入
const setInputValue = (tip) => {
  inputText.value = tip;
};
//重置
const clearAll = () => {

  inputText.value = "";
  outputText.value = "";
};
//gpt对话
const chatPost = () => {
    const messages = [{
    role: 'user',
    content: inputText.value,
  }];
  debugger
  fetchSSE(messages, {
    success(result) {
      // loading.value = false;
      const { data } = result;
      outputText.value += data?.delta?.content;
    },
    complete(isOk, msg) {
      if (!isOk || !outputText.value) {
        // lastItem.role = 'error';
        outputText.value = msg;
      }
      // 控制终止按钮
      // isStreamLoad.value = false;
      // loading.value = false;
    },
    cancel(cancel) {
      // fetchCancel.value = cancel;
    },
  });
};

/**
 * 解析SSE数据
 */
const fetchSSE = async (messages, options) => {
  const { success, fail, complete, cancel } = options;
  const controller = new AbortController();
  const { signal } = controller;
  cancel?.(controller);
  // your-api-key
  // const apiKey="S8DOQAPSFBQA6VRH9ECULPNM1BKZTCQBRGLLJWR0";   //gitee ai 的key 可以替换成你自己的key
  const responsePromise = fetch('/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer${apiKey ? ` ${apiKey}` : ''}`,
    },
    body: JSON.stringify({
      messages, // 消息列表
      model:"DeepSeek-R1-Distill-Qwen-14B",
      stream: true, // 流式
    }),
    signal,
  }).catch((e) => {
    const msg = e.toString() || '流式接口异常';
    complete?.(false, msg);
    return Promise.reject(e); // 确保错误能够被后续的.catch()捕获
  });

  responsePromise
    .then((response) => {
      if (!response?.ok) {
        complete?.(false, response.statusText);
        fail?.();
        throw new Error('Request failed'); // 抛出错误以便链式调用中的下一个.catch()处理
      }
      const reader = response.body.getReader();
      const decoder = new TextDecoder();
      if (!reader) throw new Error('No reader available');

      const bufferArr = [];
      let dataText = ''; // 记录数据
      const event = { type: null, data: null };

      async function processText({ done, value }) {
        if (done) {
          complete?.(true);
          return Promise.resolve();
        }
        const chunk = decoder.decode(value);
        const buffers = chunk.toString().split(/\r?\n/);
        bufferArr.push(...buffers);
        let i = 0;
        while (i < bufferArr.length) {
          const line = bufferArr[i];
          if (line) {
            dataText += line;
            const response = line.slice(6);
            if (response === '[DONE]') {
              event.type = 'finish';
              dataText = '';
            } else {
              try {
                const choices = JSON.parse(response.trim())?.choices?.[0];
                if (choices.finish_reason === 'stop') {
                  event.type = 'finish';
                  dataText = '';
                } else {
                  event.type = 'delta';
                  event.data = choices;
                }
              } catch (error) {
                console.error('解析错误:', error);
              }
            }
          }
          if (event.type && event.data) {
            const jsonData = { ...event };
            success(jsonData);
            event.type = null;
            event.data = null;
          }
          bufferArr.splice(i, 1);
        }
        return reader.read().then(processText);
      }

      return reader.read().then(processText);
    })
    .catch(() => {
      // 处理整个链式调用过程中发生的任何错误
      fail?.();
    });
};
</script>
<style lang="less" scoped>
.home {
  width: 100%;
  height: 100%;
}
.header {
  display: flex;
  padding: 0 20px;
  justify-content: space-between;
  // background: #333;
  // background-image: linear-gradient(135deg, #9708cc 10%, #43cbff 100%);
  background: #333;
  color: #fff;
  line-height: 60px;
  .title {
    color: #fff;
    font-size: 24px;
    // width: 30%;
  }
  .menu {
    display: flex;
    margin-right: 200px;
    .item {
      color: #fff;
      margin: 0 25px;
      font-size: 18px;
      font-weight: 800;
      cursor: pointer;
    }
    .active {
      color: #ffca28;
      font-weight: 800;
    }
  }
}
.container {
  padding: 0 20px;
  .example {
    margin: 15px 0;
    .title {
      text-align: left;
      font-size: 18px;
      font-weight: 800;
    }
    .item {
      width: 50%;
      text-align: left;
      padding: 5px 10px;
      border: 1px solid #882cd6;
      border-radius: 8px;
      cursor: pointer;
      color: #882cd6;
    }
  }
  .content {
    display: flex;
    justify-content: space-between;

    .inputWrap {
      width: 49%;
      .title {
        font-size: 18px;
        font-weight: 800;
        text-align: left;
      }
    }
    .outputWrap {
      width: 49%;
      .title {
        font-size: 18px;
        font-weight: 800;
        text-align: left;
      }
    }
  }
}
.footBtn {
  margin-top: 20px;
}
</style>
